package org.jeecg.modules.wlhy.customer.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.constant.CacheConstant;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.system.base.controller.JeecgController;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.util.ExcelUtil;
import org.jeecg.modules.system.constant.UserTypeEnum;
import org.jeecg.modules.system.entity.SysUser;
import org.jeecg.modules.system.service.ISysUserService;
import org.jeecg.modules.third.dongjiang.tax.system.dto.ApiBaseResDTO;
import org.jeecg.modules.wlhy.customer.dto.ImportHyCustomerDTO;
import org.jeecg.modules.wlhy.customer.entity.HyCustomer;
import org.jeecg.modules.wlhy.customer.service.IHyCustomerService;
import org.jeecg.modules.wlhy.hydriver.entity.ImportFBFHyCustomerDTO;
import org.jeecg.modules.wlhy.hyproject.service.IHyProjectService;
import org.jeecg.modules.wlhy.report.OrdosReportService;
import org.jeecg.modules.wlhy.setting.service.IHySettingService;
import org.jeecg.modules.wlhy.utils.DataMaskingUtil;
import org.jeecg.modules.wlhy.utils.UserUtil;
import org.jeecgframework.poi.excel.ExcelExportUtil;
import org.jeecgframework.poi.excel.entity.ExportParams;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description: hy_customer货主管理
 * @Author: jeecg-boot
 * @Date: 2020-11-30
 * @Version: V1.0
 */
@Api(tags = "hy_customer")
@RestController
@RequestMapping("/customer/hyCustomer")
//@RequiresRoles(value={"admin", "customer", "driver"},logical = Logical.OR)
@Slf4j
public class HyCustomerController extends JeecgController<HyCustomer, IHyCustomerService> {
    @Autowired
    private IHyCustomerService hyCustomerService;

    @Autowired
    private ISysUserService userService;

    @Autowired
    private IHyProjectService hyProjectService;

    @Autowired
    private OrdosReportService ordosReportService;

    @Resource
    private IHySettingService settingService;

    @Autowired
    private UserUtil userUtil;


    //天津东疆税务局上传发布方（货主）信息
    @PostMapping(value = "/tjTaxUpload")
    public Result<?> tjTaxUpload(@RequestBody HyCustomer hyCustomer) {
        ApiBaseResDTO apiBaseResDTO = hyCustomerService.tjTaxUpload(hyCustomer);
        int resCode = StringUtils.isNotEmpty(apiBaseResDTO.getCode()) ? Integer.parseInt(apiBaseResDTO.getCode()) : 0;
        if (resCode >= 100 && resCode < 200) {
            return Result.OK("发布方（货主）信息上报成功");
        } else {
            return Result.error("上报失败！" + apiBaseResDTO.getDesc());
        }
    }

    //快货运上报托运人信息（货主）
    @PostMapping(value = "/tosUpload")
    public Result<?> tosUpload(@RequestBody HyCustomer hyCustomer) {
        return hyCustomerService.tosUploadCustomer(hyCustomer);
    }

    /**
     * 分页列表查询
     *
     * @param hyCustomer
     * @param pageNo
     * @param pageSize
     * @param req
     * @return
     */

    @ApiOperation(value = "hy_customer-分页列表查询", notes = "hy_customer-分页列表查询")
    @GetMapping(value = "/list")
    public Result<?> queryPageList(HyCustomer hyCustomer,
                                   @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                   @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
                                   HttpServletRequest req) {
        QueryWrapper<HyCustomer> queryWrapper = QueryGenerator.initQueryWrapper(hyCustomer, req.getParameterMap());
        queryWrapper.in("examine_status", "0", "3");
        Page<HyCustomer> page = new Page<HyCustomer>(pageNo, pageSize);
        IPage<HyCustomer> pageList = hyCustomerService.page(page, queryWrapper);
        return Result.OK(pageList);
    }


    @ApiOperation(value = "hy_customer-分页列表查询", notes = "hy_customer-分页列表查询")
    @GetMapping(value = "/list1")
    public Result<?> queryPageList1(HyCustomer hyCustomer,
                                    @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                    @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
                                    HttpServletRequest req) {
        QueryWrapper<HyCustomer> queryWrapper = QueryGenerator.initQueryWrapper(hyCustomer, req.getParameterMap());



        queryWrapper.eq("examine_status", "1");
        Page<HyCustomer> page = new Page<HyCustomer>(pageNo, pageSize);
        IPage<HyCustomer> pageList = hyCustomerService.page(page, queryWrapper);
        return Result.OK(pageList);
    }

    @ApiOperation(value = "hy_customer-分页列表查询", notes = "hy_customer-分页列表查询")
    @GetMapping(value = "/list2")
    public Result<?> queryPageList2(HyCustomer hyCustomer,
                                    @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                    @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
                                    HttpServletRequest req) {

        QueryWrapper<HyCustomer> queryWrapper = new QueryWrapper<>();
        String customerName = hyCustomer.getCustomerName();
        if(StringUtils.isNotBlank(customerName)){
            queryWrapper.like("customer_name",customerName);
            hyCustomer.setCustomerName("");
        }
        if (userUtil.getLoginUser().getUType().equals(UserTypeEnum.业务管理员.getCode())){
            queryWrapper.in("id", userUtil.getCustomerAdminRelationIdList());
        }

        QueryGenerator.initQueryWrapper(queryWrapper , hyCustomer, req.getParameterMap());

//        queryWrapper.eq("examine_status", "2");
        Page<HyCustomer> page = new Page<HyCustomer>(pageNo, pageSize);
        IPage<HyCustomer> pageList = hyCustomerService.page(page, queryWrapper);

        //如果开启系统脱敏
        String dataMaskingFlag = this.settingService.getSettingValueByTag("data_masking");
        if("1".equals(dataMaskingFlag)) {
            for (HyCustomer dto : pageList.getRecords()) {
                dto.setLegalPhone(DataMaskingUtil.phoneMasking(dto.getLegalPhone()));
                dto.setLoginPhone(DataMaskingUtil.phoneMasking(dto.getLoginPhone()));
                dto.setCreditCode(DataMaskingUtil.bankNumberMasking(dto.getCreditCode()));
            }
        }

        return Result.OK(pageList);
    }


    @ApiOperation(value = "hy_customer-分页列表查询", notes = "hy_customer-分页列表查询")
    @GetMapping(value = "/listOfReport")
    public Result<?> queryPageListOfReport(HyCustomer hyCustomer,
                                    @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                    @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
                                    HttpServletRequest req) {

        QueryWrapper<HyCustomer> queryWrapper = new QueryWrapper<>();
        String customerName = hyCustomer.getCustomerName();
        if(StringUtils.isNotBlank(customerName)){
            queryWrapper.like("customer_name",customerName);
            hyCustomer.setCustomerName("");
        }

        QueryGenerator.initQueryWrapper(queryWrapper , hyCustomer, req.getParameterMap());

        Page<HyCustomer> page = new Page<HyCustomer>(pageNo, pageSize);
        IPage<HyCustomer> pageList = hyCustomerService.page(page, queryWrapper);

        return Result.OK(pageList);
    }


    @AutoLog(value = "ordos货主上报")
    @ApiOperation(value="ordos货主上报", notes="ordos货主上报")
    @PutMapping(value = "/customerupload")
    public Result<?> customerupload(@RequestBody HyCustomer hyCustomer) {
        return this.ordosReportService.reportCustomer(hyCustomer.getId(), "3000");
    }


    /**
     * 添加
     *
     * @param hyCustomer
     * @return
     */
    @AutoLog(value = "hy_customer-添加")
    @ApiOperation(value = "hy_customer-添加", notes = "hy_customer-添加")
    @PostMapping(value = "/add")
    public Result<?> add(@RequestBody HyCustomer hyCustomer) {

        hyCustomer.setExamineStatus("2");//平台添加审核通过
        hyCustomer.setCustomerChannel("1");//平台端添加
        if(StringUtils.isEmpty(hyCustomer.getCustomerShoreName())){
            return Result.error("简称不能为空");
        }
        if(hyCustomer.getCustomerShoreName().length() > 20){
            return Result.error("简称长度不能超过20个字");
        }
        //hyCustomer.setExamineStatus("0");
        hyCustomerService.saveCustomer(hyCustomer);
        return Result.OK("添加成功！");
    }

    /**
     * 编辑
     *
     * @param hyCustomer
     * @return
     */
    @AutoLog(value = "hy_customer-编辑")
    @ApiOperation(value = "hy_customer-编辑", notes = "hy_customer-编辑")
    @PutMapping(value = "/edit")
    @Transactional
    //@RequiresPermissions("sys:customer:edit")
    @CacheEvict(value = CacheConstant.SYS_DICT_TABLE_CACHE ,key = "'SimpleKey [hy_customer,customer_name,id,' + #hyCustomer.id + ']'")
    public Result<?> edit(@RequestBody HyCustomer hyCustomer) {

        HyCustomer customer = hyCustomerService.getById(hyCustomer.getId());
        if (customer == null) {
            return Result.error("数据不存在");
        }
        if ("1".equals(hyCustomer.getCustomerType())) {
            hyCustomer.setCustomerName(hyCustomer.getContactName());
        }
        if(StringUtils.isEmpty(hyCustomer.getCustomerShoreName())){
            return Result.error("简称不能为空");
        }
        if(hyCustomer.getCustomerShoreName().length() > 20){
            return Result.error("简称长度不能超过20个字");
        }
        String loginPhone = hyCustomer.getLoginPhone();
        if (StringUtils.isBlank(loginPhone)) {
            return Result.error("登陆手机号不能为空");
        }
        //处理登陆手机号问题
        if (!StringUtils.equals(customer.getLoginPhone(), loginPhone)) {
            int count = userService.count(new QueryWrapper<SysUser>()
                    .eq("phone", loginPhone)
                    .ne("id", hyCustomer.getUserId())
            );
            if (count > 0) {
                return Result.error("手机号已存在");
            }

            SysUser user = userService.getById(hyCustomer.getUserId());
            if (user == null) {
                return Result.error("用户信息不存在");
            }
            user.setPhone(loginPhone);
            userService.updateById(user);
            //修改
        }
        if (!StringUtils.equals(customer.getCustomerName(), hyCustomer.getCustomerName())) {
            SysUser user = userService.getById(hyCustomer.getUserId());
            if (user == null) {
                return Result.error("用户信息不存在");
            }
            user.setRealname(hyCustomer.getCustomerName());
            userService.updateById(user);
        }

        hyCustomerService.updateById(hyCustomer);
        return Result.OK("编辑成功!");
    }

    @AutoLog(value = "hy_customer-提交审核")
    @ApiOperation(value = "hy_customer-提交审核", notes = "hy_customer-提交审核")
    @PutMapping(value = "/aut1")
    public Result<?> aut1(@RequestBody HyCustomer hyCustomer) {
        hyCustomer.setExamineStatus("1");
        hyCustomer.setExamineDate(new Date());
        hyCustomerService.updateById(hyCustomer);
        return Result.OK("提交审核成功!");
    }

    @AutoLog(value = "hy_customer-审核")
    @ApiOperation(value = "hy_customer-审核", notes = "hy_customer-审核")
    @PutMapping(value = "/aut2")
    @RequiresPermissions("sys:customer:aut2")
    public Result<?> aut2(@RequestBody HyCustomer hyCustomer) {
        //hyCustomer.setExamineStatus("2");
        hyCustomer.setExamineDate(new Date());
        hyCustomerService.updateById(hyCustomer);
//		 HyCustomer hyCustomerDb = hyCustomerService.getById(hyCustomer.getId());
//		 LoginUser loginUser = UserUtil.getLoginUser();
//		 HyWarningMessage hyWarningMessage = new HyWarningMessage();
//		 hyWarningMessage.setObjectId(hyCustomer.getId());
//		 hyWarningMessage.setUserId(hyCustomerDb.getUserId());
//		 hyWarningMessage.setMessageType(MessageTypeEnum.MESSAGE_TYPE_HZSH.getCode());
//		 hyWarningMessage.setMessageContent(
//		 		"货主:"+hyCustomerDb.getCustomerName()+" 已审核通过!"
//		 );
//		 hyWarningMessage.setCreateBy(loginUser.getUsername());
//		 hyWarningMessage.setCreateTime(new Date());
//		 hyWarningMessageService.saveWarningMessage(hyWarningMessage);
        return Result.OK("审核成功!");
    }

    /**
     * 通过id删除
     *
     * @param id
     * @return
     */
    @AutoLog(value = "hy_customer-通过id删除")
    @ApiOperation(value = "hy_customer-通过id删除", notes = "hy_customer-通过id删除")
    @DeleteMapping(value = "/delete")
    public Result<?> delete(@RequestParam(name = "id", required = true) String id) {
        hyCustomerService.removeById(id);
        return Result.OK("删除成功!");
    }

    /**
     * 批量删除
     *
     * @param ids
     * @return
     */
    @AutoLog(value = "hy_customer-批量删除")
    @ApiOperation(value = "hy_customer-批量删除", notes = "hy_customer-批量删除")
    @DeleteMapping(value = "/deleteBatch")
    public Result<?> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
        this.hyCustomerService.removeByIds(Arrays.asList(ids.split(",")));
        return Result.OK("批量删除成功!");
    }

    /**
     * 通过id查询
     *
     * @param id
     * @return
     */

    @ApiOperation(value = "hy_customer-通过id查询", notes = "hy_customer-通过id查询")
    @GetMapping(value = "/queryById")
    public Result<?> queryById(@RequestParam(name = "id", required = true) String id) {
        HyCustomer hyCustomer = hyCustomerService.getById(id);
        if (hyCustomer == null) {
            return Result.error("未找到对应数据");
        }
        return Result.OK(hyCustomer);
    }

    /**
     * 导出excel
     *
     * @param request
     * @param hyCustomer
     */
    @RequestMapping(value = "/exportXls")
    public ModelAndView exportXls(HttpServletRequest request, HyCustomer hyCustomer) {
        return super.exportXls(request, hyCustomer, HyCustomer.class, "hy_customer");
    }

    /**
     * 通过excel导入数据
     *
     * @param request
     * @param response
     * @return
     */
    @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
    public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
        return super.importExcel(request, response, HyCustomer.class);
    }


    /**
     * 通过excel导入货主
     *
     * @param request
     * @param response
     * @return
     */
    @RequestMapping(value = "/importCustomer", method = RequestMethod.POST)
    public Result<?> importCustomer(HttpServletRequest request, HttpServletResponse response) {
        List<ImportHyCustomerDTO> list = ExcelUtil.importExcel(request, ImportHyCustomerDTO.class);
        if(CollectionUtils.isEmpty(list)) {
            return Result.error("导入货主数据不能为空！");
        }

        this.checkData(list);
        //查询货主是否已经存在
        List<String> customerNames = list.stream().map(
                item -> item.getCustomerName().trim()
        ).distinct().filter(Objects::nonNull).collect(Collectors.toList());

        List<HyCustomer> hyCustomersDB = this.hyCustomerService.list();
        if (hyCustomersDB.size() > 0) {
            List<String> dbCustomerNames = hyCustomersDB.stream().map(
                    item -> item.getCustomerName()
            ).collect(Collectors.toList());

            List<String> filterNames = customerNames.stream()
                    .filter(item -> dbCustomerNames.contains(item))
                    .collect(Collectors.toList());
            log.info("校验是否有重复货主信息, {}", JSONUtil.toJsonStr(filterNames));
            if (CollUtil.isNotEmpty(filterNames)) {
                return Result.error(JSONUtil.toJsonStr(filterNames) + ",货主数据信息已存在");
            }
        }

        this.hyCustomerService.saveCustomerBatch(list);
        return Result.OK("文件导入成功！数据行数：" + list.size());
    }

    @GetMapping(value = "/getdaishenqhuozhu")
    public Result<?> getdaishenqhuozhu() {
        int count = hyCustomerService.count(new QueryWrapper<HyCustomer>().eq("examine_status",1));
        return Result.OK(count);
    }

    /**
     * 通过excel导入数据
     * @param request
     * @return
     */
    @RequestMapping(value = "/importCustomer2", method = RequestMethod.POST)
//	@RequiresPermissions("sys:driver:importExcel")
    public Result<?> importCustomer2(HttpServletRequest request,HttpServletResponse response) throws IOException {
        List<ImportFBFHyCustomerDTO> list = ExcelUtil.importExcel(request, ImportFBFHyCustomerDTO.class);
        if(CollectionUtils.isEmpty(list)) {
            return Result.error("导入数据不能为空！");
        }

        this.checkDataCustomer(list);
        //身份证号查询司机是否存在
        List<String> customerLicenses = list.stream().map(
                item -> item.getNSRSBH().trim()
        ).distinct().filter(Objects::nonNull).collect(Collectors.toList());


        int section = 10;
        List<HyCustomer> customerList = new LinkedList<>() ;
        for (int index = 0, end = 0; index < customerLicenses.size(); index = end) {
            end = (end + section) <= customerLicenses.size() ? end + section : customerLicenses.size();
            if (index < end) {
                QueryWrapper <HyCustomer> querydriverWrapper = new QueryWrapper();
                querydriverWrapper.in("credit_code" ,customerLicenses.subList(index, end));
                customerList.addAll(hyCustomerService.list(querydriverWrapper));
            }
        }
        //空间换时间 降低时间复杂度
        Map<String, ImportFBFHyCustomerDTO> tempMap = new HashMap<>();
        for(ImportFBFHyCustomerDTO str:list){
            tempMap.put(str.getNSRSBH(),str);
        }
        for (HyCustomer customer : customerList) {
            if(tempMap.containsKey(customer.getCreditCode())){
                customer.setFbfuuid(tempMap.get(customer.getCreditCode()).getFbFUUID());
                list.remove(tempMap.get(customer.getCreditCode()));
            }
        }
        Integer failCount=0;
        failCount=list.size();
        hyCustomerService.updateBatchById(customerList);
        if(failCount==0){
            return Result.ok("文件导入成功！数据条数：" + customerList.size()+"条");
        }
        ExportParams exportParams = new ExportParams(null,"title");
        exportParams.setAddIndex(false);
        Workbook sheets = ExcelExportUtil.exportExcel(exportParams, ImportFBFHyCustomerDTO.class, list);
        response.setHeader("Access-Control-Expose-Headers", "content-disposition");
        response.setHeader("content-disposition", "attachment;filename="
                + URLEncoder.encode("未匹配成功的数据.xlsx", "UTF-8")
                +";"
                +URLEncoder.encode("文件导入成功的数据条数"+ customerList.size()+"条。"+"未匹配成功的数据条数"+failCount+"条。", "UTF-8"));
        ServletOutputStream out = response.getOutputStream();
        sheets.write(out);
        out.flush();
        return Result.error(-99,"");

    }

    private  void checkDataCustomer(List<ImportFBFHyCustomerDTO> list){
        int i = 2;
        for(ImportFBFHyCustomerDTO importHyDriverDTO :list){
            String key = String.valueOf(i);

            if (StringUtils.isBlank(importHyDriverDTO.getFbFUUID())) {
                throw new JeecgBootException("第"+ key+ "行uuid不能为空,请先补充信息");
            }
            if (StringUtils.isBlank(importHyDriverDTO.getNSRMC())) {
                throw new JeecgBootException("第"+ key+ "行纳税人名称不能为空,请先补充信息");
            }
            if (StringUtils.isBlank(importHyDriverDTO.getNSRSBH())) {
                throw new JeecgBootException("第"+ key+ "行纳税人识别号不能为空,请先补充信息");
            }

            i++;
        }
    }

    private void checkData(List<ImportHyCustomerDTO> list){
        int i = 2;
        for(ImportHyCustomerDTO importCustomer :list){
            String key = String.valueOf(i);

            if (StringUtils.isBlank(importCustomer.getLoginPhone())) {
                throw new JeecgBootException("第"+ key+ "行登录手机号不能为空,请先补充信息");
            }
            if (StringUtils.isBlank(importCustomer.getCustomerType())) {
                throw new JeecgBootException("第"+ key+ "行客户类型不能为空,请先补充信息");
            }
            if (StringUtils.isBlank(importCustomer.getCustomerChannel())) {
                throw new JeecgBootException("第"+ key+ "行客户来源不能为空,请先补充信息");
            }
            if (StringUtils.isBlank(importCustomer.getCustomerName())) {
                throw new JeecgBootException("第"+ key+ "行客户名称不能为空,请先补充信息");
            }
            if (StringUtils.isBlank(importCustomer.getCustomerShoreName())) {
                throw new JeecgBootException("第"+ key+ "行客户简称不能为空,请先补充信息");
            }
            if (StringUtils.isBlank(importCustomer.getCreditCode())) {
                throw new JeecgBootException("第"+ key+ "行社会信用代码证不能为空,请先补充信息");
            }

            i++;
        }
    }
}
